/*
 * WebSocketClient.ino
 *
 *  Created on: 24.05.2015
 *
 */

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h>
#include <Hash.h>
#include <ArduinoJson.h>

ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;

#define USE_SERIAL Serial
#define LED_ON LOW
#define LED_OFF HIGH

char sn[10] = "a123456";
unsigned long freq = 5000;
unsigned long hand_delay = 30000;
unsigned long hand_start_time = 0;
char hand_flag = 0;

void webSocketEvent(WStype_t type, uint8_t *payload, size_t length)
{
  switch (type)
  {
  case WStype_DISCONNECTED:
    USE_SERIAL.printf("[WSc] Disconnected!\n");
    break;
  case WStype_CONNECTED:
  {
    USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
    //注册连接
    char msg[64] = "";
    webSocket.sendTXT(sprintf(msg, "{\"type\":1,\"sn\":\"%s\"}", sn));
  }
  break;
  case WStype_TEXT:
  {
    USE_SERIAL.printf("[WSc] get text: %s\n", payload);
    //解析数据
    StaticJsonDocument<400> doc;
    DeserializationError error = deserializeJson(doc, payload);

    // Test if parsing succeeds.
    if (error)
    {
      Serial.print(F("deserializeJson() failed: "));
      break;
    }
    int msgType = doc["type"];
    Serial.println(msgType);
    switch (msgType)
    {
    case 2:
    {
      if (!hand_flag)
      {
        char status = doc["status"];
        if (status)
        {
          digitalWrite(2, LED_ON);
        }
        else
        {
          digitalWrite(2, LED_OFF);
        }
      }
    }
    break;
    case 3: //手动控制
    {
      char status = doc["status"];
      if (status)
      {
        digitalWrite(2, LED_ON);
      }
      else
      {
        digitalWrite(2, LED_OFF);
      }
      hand_flag = 1;
      hand_start_time = millis();
    }

    break;
    case 4: //设置
    {
      freq = doc["freq"];
      hand_delay = doc["hand_delay"];
      Serial.println(freq);
      Serial.println(hand_delay);
    }

    break;
    default:
      break;
    }
  }
  break;
  case WStype_BIN:
    USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
    hexdump(payload, length);

    // send data to server
    // webSocket.sendBIN(payload, length);
    break;
  case WStype_PING:
    // pong will be send automatically
    USE_SERIAL.printf("[WSc] get ping\n");
    break;
  case WStype_PONG:
    // answer to a ping we send
    //USE_SERIAL.printf("[WSc] get pong\n");
    break;
  default:
    break;
  }
}

void setup()
{
  //LED
  pinMode(2, OUTPUT);
  USE_SERIAL.begin(9600);

  USE_SERIAL.println();
  USE_SERIAL.println();
  USE_SERIAL.println();

  for (uint8_t t = 4; t > 0; t--)
  {
    USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
    USE_SERIAL.flush();
    delay(1000);
  }

  WiFiMulti.addAP("AcTek_Wifi", "actek888");
  while (WiFiMulti.run() != WL_CONNECTED)
  {
    delay(100);
  }
  webSocket.begin("192.168.88.198", 9501, "/");
  webSocket.onEvent(webSocketEvent);
  webSocket.setReconnectInterval(5000);
  webSocket.enableHeartbeat(15000, 3000, 2);
}

unsigned long n = 0;

void loop()
{
  //上传数据
  if (millis() - n > freq)
  {
    int lux = analogRead(A0);
    char msg[128] = "";
    sprintf(msg, "{\"type\":2,\"data\":%d,\"sn\":\"%s\"}", lux, sn);
    webSocket.sendTXT(msg);
    n = millis();
  }
  //手动控制延时
  if (hand_flag && millis() - hand_start_time > hand_delay)
  {
    hand_flag = 0;
  }
  webSocket.loop();
}
